package com.zhiche.lisa.bms.service.psup.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.google.common.collect.Lists;
import com.zhiche.lisa.bms.constant.DWaybillFeeEnum;
import com.zhiche.lisa.bms.dao.model.driver.VehicleClassify;
import com.zhiche.lisa.bms.dao.model.fee.FeePayable;
import com.zhiche.lisa.bms.dao.model.psup.*;
import com.zhiche.lisa.bms.enums.SdCommonEnum;
import com.zhiche.lisa.bms.pojo.vo.psup.PsupOilPriceVO;
import com.zhiche.lisa.bms.pojo.vo.psup.SdRuleMatchVO;
import com.zhiche.lisa.bms.service.driver.ICalcDriverCost;
import com.zhiche.lisa.bms.service.driver.IVehicleClassifyService;
import com.zhiche.lisa.bms.service.psup.*;
import com.zhiche.lisa.bms.utils.KieUtil;
import com.zhiche.lisa.bms.utils.ToolCommonUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.rule.FactHandle;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

/**
 * @author linbao
 * @date 2019-06-20
 */
@Service
@Slf4j
public class SdBaseComputerServiceImpl implements SdBaseComputerService {

    @Autowired
    private PsupBaseDataService psupBaseDataService;

    @Autowired
    private PsupFixedPriceService psupFixedPriceService;

    @Autowired
    private PsupOtherExpensisesService psupOtherExpensisesService;

    @Autowired
    private PsupVehicleContrastService psupVehicleContrastService;

    @Autowired
    private PsupTraditionPriceService psupTraditionPriceService;

    @Autowired
    private ICalcDriverCost calcDriverCost;

    @Autowired
    private PsupOilpriceService psupOilpriceService;

    @Autowired
    private PsupPriceRateService psupPriceRateService;

    @Autowired
    private IVehicleClassifyService vehicleClassifyService;

    /**
     * 获取人送基础数据车队信息
     *
     * @return
     */
    @Override
    public Set<Long> getSdBaseDataFleetIdSet() {
        Set<Long> fleetIdSet = new HashSet<>();
        EntityWrapper<PsupBaseData> ew = new EntityWrapper<>();
        ew.setSqlSelect("distinct fleet_id");
        ew.eq("status", SdCommonEnum.AUDIT.getCode());
        List<Object> objectList = psupBaseDataService.selectObjs(ew);
        if (CollectionUtils.isNotEmpty(objectList)) {
            objectList.forEach(obj -> {
                fleetIdSet.add(Long.valueOf(obj.toString()));
            });
        }
        return fleetIdSet;
    }


    /**
     * 计算人送供方价格数据
     *
     * @param feePayable
     */
    @Override
    public void computerFeePayableSendByDriver(FeePayable feePayable) {
        log.info("SdBaseComputerServiceImpl.computerFeePayableSendByDriver param: {}", feePayable);
        FeePayable newMatchFeePayable = new FeePayable();
        BeanUtils.copyProperties(feePayable, newMatchFeePayable);
        newMatchFeePayable.setActualAmt(null);
        newMatchFeePayable.setActualPrice(null);
        newMatchFeePayable.setKilometre(null);

        // 标准车型转换合同车型
        PsupVehicleContrast vehicleContrast = getVehicleContrast(newMatchFeePayable.getVehicleTypeCode());
        String oldVehicleName = newMatchFeePayable.getVehicleTypeCode();
        if (Objects.nonNull(vehicleContrast) && StringUtils.isNotBlank(vehicleContrast.getCnVehicle())) {
            newMatchFeePayable.setVehicleClassifyId(vehicleContrast.getCnVehicle());
        } else {
            newMatchFeePayable.setVehicleClassifyId(null);
            // return;
        }
        // 匹配基础数据信息 - 价格模式
        List<PsupBaseData> matchSdBaseDataInfoList = getMatchSdBaseDataInfo(newMatchFeePayable);
        if (CollectionUtils.isEmpty(matchSdBaseDataInfoList)) {
            return;
        }
        // 循环处理数据
        for (PsupBaseData psupBaseData : matchSdBaseDataInfoList) {
            if (Objects.nonNull(psupBaseData.getPriceModel())) {
                // 判断价格模式
                if (SdCommonEnum.PRICE_MODEL_TRADITION.getCode().equals(psupBaseData.getPriceModel())) {
                    // 传统价格模式
                    if (Objects.nonNull(vehicleContrast) && Objects.nonNull(vehicleContrast.getOilType())) {
                        this.dealSdTraditionPriceModel(newMatchFeePayable, psupBaseData, vehicleContrast.getOilType());
                    } else {
                        this.dealSdTraditionPriceModel(newMatchFeePayable, psupBaseData, null);
                    }
                    if (verifyIsActuurial(newMatchFeePayable)) {
                        updatePrice(feePayable, newMatchFeePayable, psupBaseData);
                        dealOtherExpensises(feePayable, vehicleContrast);
                        break;
                    }
                } else if (SdCommonEnum.PRICE_MODEL_FIXED_PRICE.getCode().equals(psupBaseData.getPriceModel())) {
                    // 一口价模式
                    this.dealFixedPriceModel(newMatchFeePayable);
                    if (verifyIsActuurial(newMatchFeePayable)) {
                        updatePrice(feePayable, newMatchFeePayable, psupBaseData);
                        dealOtherExpensises(feePayable, vehicleContrast);
                        break;
                    }
                } else if (SdCommonEnum.PRICE_MODEL_DRIVER_SEND.getCode().equals(psupBaseData.getPriceModel())) {
                    // 人送价格模式
                    this.dealSendByDriverModel(newMatchFeePayable, oldVehicleName);
                    if (verifyIsActuurial(newMatchFeePayable)) {
                        updatePrice(feePayable, newMatchFeePayable, psupBaseData);
                        dealOtherExpensises(feePayable, vehicleContrast);
                        break;
                    }
                }
            }
        }
    }

    /**
     * 更新价格 - 总价格还要价格比例
     *
     * @param oldFeePayable
     * @param priceFeePayable
     * @param psupBaseData
     */
    private void updatePrice(FeePayable oldFeePayable, FeePayable priceFeePayable, PsupBaseData psupBaseData) {
        oldFeePayable.setPsupRemark(priceFeePayable.getPsupRemark());
        oldFeePayable.setActualPrice(priceFeePayable.getActualPrice());
        oldFeePayable.setKilometre(priceFeePayable.getKilometre());
        if (Objects.nonNull(priceFeePayable.getActualAmt()) && BigDecimal.ZERO.compareTo(priceFeePayable.getActualAmt()) != 0) {
            oldFeePayable.setActualAmt(priceFeePayable.getActualAmt());
        } else {
            oldFeePayable.setActualAmt(priceFeePayable.getKilometre().multiply(priceFeePayable.getActualPrice()));
        }

        // 价格比例
        if (Objects.nonNull(oldFeePayable.getActualAmt())) {
            if (Objects.nonNull(psupBaseData.getCashFinalRate())) {
                oldFeePayable.setCashBaPay(oldFeePayable.getActualAmt().multiply(psupBaseData.getCashFinalRate()).setScale(2, BigDecimal.ROUND_HALF_UP));
            }
            if (Objects.nonNull(psupBaseData.getOilFinalRate())) {
                oldFeePayable.setOilBaPay(oldFeePayable.getActualAmt().multiply(psupBaseData.getOilFinalRate()).setScale(2, BigDecimal.ROUND_HALF_UP));
            }
        }
    }

    /**
     * 传统价格模式
     *
     * @param feePayable
     */
    private void dealSdTraditionPriceModel(FeePayable feePayable, PsupBaseData psupBaseData, Integer oilType) {
        // psupTraditionPriceService.
        // 匹配对应的已审核且对应车队有效期内的数据
        EntityWrapper<PsupTraditionPrice> ew = getCommonWrapper(feePayable);
        if (StringUtils.isNotBlank(feePayable.getVehicleClassifyId())) {
            ew.andNew().eq("contract_vehicle", feePayable.getVehicleClassifyId()).or().isNull("contract_vehicle");
        } else {
            ew.isNull("contract_vehicle");
        }
        List<PsupTraditionPrice> psupTraditionPriceList = psupTraditionPriceService.selectList(ew);
        if (CollectionUtils.isNotEmpty(psupTraditionPriceList)) {
            List<SdRuleMatchVO> sdRuleMatchVOList = this.changeTraditionPriceToRuleMatch(psupTraditionPriceList);
            matchSdRule(feePayable, sdRuleMatchVOList);
            if (verifyIsActuurial(feePayable)) {
                // 是否油价联动
                if (SdCommonEnum.IS_LINK_YES.getCode().equals(psupBaseData.getLinkFlag()) && Objects.nonNull(oilType)) {
                    // 油价联动 - 获取市场油价
                    PsupOilPriceVO oilPriceVo = new PsupOilPriceVO();
                    oilPriceVo.setOilType(oilType);
                    oilPriceVo.setEffectiveDate(feePayable.getOrderDate());
                    PsupOilprice psupOilprice = psupOilpriceService.matchEffectiveDateOilPrice(oilPriceVo);
                    if (Objects.nonNull(psupOilprice) && Objects.nonNull(psupOilprice.getPrice())) {

                        BigDecimal subPrice = BigDecimal.ZERO;
                        if (SdCommonEnum.OIL_TYPE_0.getCode().equals(oilType) && Objects.nonNull(psupBaseData.getDieselPrice())) {
                            subPrice = psupOilprice.getPrice().subtract(psupBaseData.getDieselPrice());
                        } else if (SdCommonEnum.OIL_TYPE_92.getCode().equals(oilType) && Objects.nonNull(psupBaseData.getGasolinePrice())) {
                            subPrice = psupOilprice.getPrice().subtract(psupBaseData.getGasolinePrice());
                        }
                        if (SdCommonEnum.ZENE_AND_NOE.compareTo(subPrice.abs()) < 0) {
                            // 价格差距大于0.1
                            BigDecimal oldActualAmt = feePayable.getKilometre().multiply(feePayable.getActualPrice());
                            BigDecimal totalAmt = subPrice.setScale(1, BigDecimal.ROUND_HALF_UP).multiply(SdCommonEnum.ZENE_AND_NOE).multiply(feePayable.getKilometre()).add(oldActualAmt);
                            feePayable.setActualAmt(totalAmt);
                        } else {
                            feePayable.setActualAmt(feePayable.getActualPrice().multiply(feePayable.getKilometre()));
                        }
                        feePayable.setActualPrice(feePayable.getActualAmt().divide(feePayable.getKilometre(), 4, BigDecimal.ROUND_HALF_UP).setScale(4, BigDecimal.ROUND_HALF_UP));
                    }
                } else {
                    // 直接计算
                    feePayable.setActualAmt(feePayable.getActualPrice().multiply(feePayable.getKilometre()));
                }
            }
        }
    }

    /**
     * 传统价格模式
     *
     * @param feePayable
     */
    private void dealFixedPriceModel(FeePayable feePayable) {
        // 车型转换

        EntityWrapper<PsupFixedPrice> ew = new EntityWrapper<>();
        ew.eq("fleet_id", feePayable.getFleetId());
        ew.eq("status", SdCommonEnum.AUDIT.getCode());
        if (Objects.nonNull(feePayable.getOrderDate())) {
            ew.le("effective_date", new DateTime(feePayable.getOrderDate()).toString(ToolCommonUtils.yyyyMMdd));
            ew.ge("invalid_date", new DateTime(feePayable.getOrderDate()).toString(ToolCommonUtils.yyyyMMdd));
        }
        if (StringUtils.isNotBlank(feePayable.getVehicleClassifyId())) {
            ew.andNew().eq("contract_vehicle", feePayable.getVehicleClassifyId()).or().isNull("contract_vehicle");
        } else {
            ew.isNull("contract_vehicle");
        }
        List<PsupFixedPrice> psupFixedPriceList = psupFixedPriceService.selectList(ew);
        if (CollectionUtils.isNotEmpty(psupFixedPriceList)) {
            List<SdRuleMatchVO> sdRuleMatchVOList = changeFixedPriceToRuleMatch(psupFixedPriceList);
            matchSdRule(feePayable, sdRuleMatchVOList);
        }
    }

    /**
     * 人送价格模式
     *
     * @param feePayable
     */
    private void dealSendByDriverModel(FeePayable feePayable, String oldVehicleName) {
        //
        try {
            if (StringUtils.isNotBlank(oldVehicleName)) {

                oldVehicleName = getSdVehicleId(oldVehicleName);
                String dTagCityAndCounty = null;
                String dTagCity = null;
                if (StringUtils.isNotBlank(feePayable.getEndCity()) && StringUtils.isNotBlank(feePayable.getEndCounty())) {
                    dTagCityAndCounty = feePayable.getEndCity() + "-" + feePayable.getEndCounty();
                }
                if (StringUtils.isNotBlank(feePayable.getEndCity())) {
                    dTagCity = feePayable.getEndCity();
                }
                if (StringUtils.isNotBlank(dTagCityAndCounty)) {
                    Map<Integer, Object> resultMap = calcDriverCost.getPriceMapForSendByDriver(oldVehicleName, feePayable.getStartProvince(),
                            feePayable.getStartCity(), feePayable.getEndProvince(),
                            dTagCityAndCounty, null, feePayable.getOrderDate());
                    if (Objects.isNull(resultMap) && StringUtils.isNotBlank(dTagCity)) {
                        resultMap = calcDriverCost.getPriceMapForSendByDriver(oldVehicleName, feePayable.getStartProvince(),
                                feePayable.getStartCity(), feePayable.getEndProvince(),
                                dTagCity, null, feePayable.getOrderDate());
                        if (Objects.nonNull(resultMap)) {
                            computeSendByDriverAndRatePrice(resultMap, feePayable);
                        }
                    } else {
                        computeSendByDriverAndRatePrice(resultMap, feePayable);
                    }
                } else if (StringUtils.isNotBlank(dTagCity)) {
                    Map<Integer, Object> resultMap = calcDriverCost.getPriceMapForSendByDriver(oldVehicleName, feePayable.getStartProvince(),
                            feePayable.getStartCity(), feePayable.getEndProvince(),
                            dTagCity, null, feePayable.getOrderDate());
                    if (Objects.nonNull(resultMap)) {
                        computeSendByDriverAndRatePrice(resultMap, feePayable);
                    }
                }
            }
        } catch (Exception e) {
            return;
        }
    }

    private String getSdVehicleId(String vehicleClasiName) {
        if (StringUtils.isNotBlank(vehicleClasiName)) {
            Wrapper<VehicleClassify> ewVehicel = new EntityWrapper();
            ewVehicel.eq("vehicle_classify_name", vehicleClasiName);
            List<VehicleClassify> dVehicleClassifyList = vehicleClassifyService.selectList(ewVehicel);
            if (CollectionUtils.isNotEmpty(dVehicleClassifyList)) {
                return dVehicleClassifyList.get(0).getVehicleClassifyId();
            }
        }
        return vehicleClasiName;
    }

    /**
     * 计算费用类型和计算价格比例
     *
     * @param resultMap
     * @param feePayable
     */
    private void computeSendByDriverAndRatePrice(Map<Integer, Object> resultMap, FeePayable feePayable) {
        BigDecimal totalOilAmt = null;
        BigDecimal totalCostAmt = null;
        BigDecimal totalTransAmt = null;
        BigDecimal subsidyAmt = null;
        // 总油费
        Object oilObj = resultMap.get(DWaybillFeeEnum.TOTAL_OIL_COST.getValue());
        if (Objects.nonNull(oilObj) && StringUtils.isNotBlank(oilObj.toString())) {
            totalOilAmt = new BigDecimal(oilObj.toString());
        }
        // 劳务费
        Object costObj = resultMap.get(DWaybillFeeEnum.LABOR_COSTS.getValue());
        if (Objects.nonNull(costObj) && StringUtils.isNotBlank(costObj.toString())) {
            totalCostAmt = new BigDecimal(costObj.toString());
        }
        // 总运费
        Object transAmtObj = resultMap.get(DWaybillFeeEnum.TOTAL_SHIPPING_COST.getValue());
        if (Objects.nonNull(transAmtObj) && StringUtils.isNotBlank(transAmtObj.toString())) {
            totalTransAmt = new BigDecimal(transAmtObj.toString());
        }
        // 补贴费用
        Object subsidyAmtObj = resultMap.get(DWaybillFeeEnum.SUBSIDY.getValue());
        if (Objects.nonNull(subsidyAmtObj) && StringUtils.isNotBlank(subsidyAmtObj.toString())) {
            subsidyAmt = new BigDecimal(subsidyAmtObj.toString());
        }

        if (Objects.nonNull(totalCostAmt) && Objects.nonNull(totalOilAmt) && Objects.nonNull(totalTransAmt)) {
            PsupPriceRate priceRate = getPriceRate(feePayable);
            if (Objects.nonNull(priceRate)) {
                if (SdCommonEnum.FLOAT_PRICE_TRADITION.getCode().equals(priceRate.getFloatPriceType())) {
                    // 运输费
                    BigDecimal rateTransAmt = totalTransAmt.multiply(priceRate.getFloatRate());
                    feePayable.setActualPrice(rateTransAmt.add(subsidyAmt));
                    feePayable.setActualAmt(feePayable.getActualPrice());
                } else if (SdCommonEnum.FLOAT_PRICE_COST.getCode().equals(priceRate.getFloatPriceType())) {
                    // 劳务费
                    BigDecimal rateCostAmt = totalCostAmt.multiply(priceRate.getFloatRate());
                    // 劳务费 + 油费
                    feePayable.setActualPrice(totalOilAmt.add(rateCostAmt));
                    feePayable.setActualAmt(feePayable.getActualPrice());
                } else if (SdCommonEnum.FLOAT_PRICE_OIL.getCode().equals(priceRate.getFloatPriceType())) {
                    // 油费
                    BigDecimal rateOilAmt = totalOilAmt.multiply(priceRate.getFloatRate());
                    feePayable.setActualPrice(totalCostAmt.add(rateOilAmt));
                    feePayable.setActualAmt(feePayable.getActualPrice());
                }
            } else {
                feePayable.setActualPrice(totalTransAmt.add(subsidyAmt));
                feePayable.setActualAmt(feePayable.getActualPrice());
            }
            feePayable.setKilometre(BigDecimal.ONE);
            feePayable.setPsupRemark("人送价格模式");
        }
    }

    /**
     * 获取对应的价格比例
     *
     * @param feePayable
     * @return
     */
    private PsupPriceRate getPriceRate(FeePayable feePayable) {
        PsupPriceRate conditionPriceRate = new PsupPriceRate();
        conditionPriceRate.setFleetId(feePayable.getFleetId());
        conditionPriceRate.setEffectiveDate(feePayable.getOrderDate());
        return psupPriceRateService.queryMatchRulePriceRate(conditionPriceRate);
    }

    /**
     * 处理其他费用
     *
     * @param feePayable
     */
    private void dealOtherExpensises(FeePayable feePayable, PsupVehicleContrast vehicleContrast) {
        FeePayable otherFeePayable = new FeePayable();
        BeanUtils.copyProperties(feePayable, otherFeePayable);
        otherFeePayable.setSdOtherExpensiseAmt(null);
        otherFeePayable.setPsupRemark(null);
        if (Objects.nonNull(vehicleContrast) && StringUtils.isNotBlank(vehicleContrast.getCnVehicle())) {
            otherFeePayable.setVehicleClassifyId(vehicleContrast.getCnVehicle());
        } else {
            otherFeePayable.setVehicleClassifyId(null);
        }


        // 找到对应的所有的其他费用类型
        EntityWrapper<PsupOtherExpensises> ew = new EntityWrapper<>();
        ew.setSqlSelect("distinct price_type");
        ew.eq("fleet_id", feePayable.getFleetId());
        ew.eq("status", SdCommonEnum.AUDIT.getCode());
        if (Objects.nonNull(feePayable.getOrderDate())) {
            ew.le("effective_date", new DateTime(feePayable.getOrderDate()).toString(ToolCommonUtils.yyyyMMdd));
            ew.ge("invalid_date", new DateTime(feePayable.getOrderDate()).toString(ToolCommonUtils.yyyyMMdd));
        }
        List<Object> prictTypeObjList = psupOtherExpensisesService.selectObjs(ew);
        if (CollectionUtils.isNotEmpty(prictTypeObjList)) {

            BigDecimal totalOtherAmt = BigDecimal.ZERO;
            StringBuilder sb = new StringBuilder();

            for (Object priceType : prictTypeObjList) {
                otherFeePayable.setActualPrice(null);
                otherFeePayable.setSdOtherExpensiseIds(null);
                otherFeePayable.setKilometre(null);
                otherFeePayable.setPsupRemark(null);
                // 处理数据 - 匹配价格
                matchOtherExpensises(otherFeePayable, priceType);
                if (Objects.nonNull(otherFeePayable.getActualPrice())) {
                    totalOtherAmt = totalOtherAmt.add(otherFeePayable.getActualPrice());
                    if (StringUtils.isNotBlank(sb)) {
                        sb.append(",");
                    }
                    sb.append(otherFeePayable.getSdOtherExpensiseIds());
                }
            }
            if (StringUtils.isNotBlank(sb)) {
                feePayable.setSdOtherExpensiseAmt(totalOtherAmt);
                feePayable.setSdOtherExpensiseIds(sb.toString());
                // 2019-07-11 修改 - 总金额 = 单价 * 公里数 + 其他费用
                feePayable.setActualAmt(feePayable.getActualAmt().add(totalOtherAmt));
            }
        }
    }

    /**
     * 匹配其他费用数据
     *
     * @param otherFeePayable
     * @param priceType
     */
    private void matchOtherExpensises(FeePayable otherFeePayable, Object priceType) {
        EntityWrapper<PsupOtherExpensises> selectEw = new EntityWrapper<>();
        selectEw.eq("fleet_id", otherFeePayable.getFleetId());
        selectEw.eq("status", SdCommonEnum.AUDIT.getCode());
        if (Objects.nonNull(otherFeePayable.getOrderDate())) {
            selectEw.le("effective_date", new DateTime(otherFeePayable.getOrderDate()).toString(ToolCommonUtils.yyyyMMdd));
            selectEw.ge("invalid_date", new DateTime(otherFeePayable.getOrderDate()).toString(ToolCommonUtils.yyyyMMdd));
        }
        selectEw.eq("price_type", priceType);
        List<PsupOtherExpensises> psupOtherExpensisesList = psupOtherExpensisesService.selectList(selectEw);
        List<SdRuleMatchVO> sdRuleMatchVOList = changeOtherExpensisesToRuleMatch(psupOtherExpensisesList);
        matchSdRule(otherFeePayable, sdRuleMatchVOList);
    }


    /**
     * 判断是否找到对应的规则
     *
     * @param feePayable
     * @return
     */
    private boolean verifyIsActuurial(FeePayable feePayable) {
        boolean reulstBoolean = false;

        if (StringUtils.isNotBlank(feePayable.getPsupRemark())
                && Objects.nonNull(feePayable.getActualPrice())
                && Objects.nonNull(feePayable.getKilometre())) {
            reulstBoolean = true;
        }
        return reulstBoolean;
    }


    /**
     * 对象转换 - 针对传统价格匹配规则
     *
     * @param traditionPriceList
     * @return
     */
    private List<SdRuleMatchVO> changeTraditionPriceToRuleMatch(List<PsupTraditionPrice> traditionPriceList) {
        List<SdRuleMatchVO> voList = Lists.newArrayList();
        traditionPriceList.forEach(traditionPrice -> {
            SdRuleMatchVO vo = new SdRuleMatchVO();
            vo.setPriceModel(SdCommonEnum.PRICE_MODEL_TRADITION.getValue());
            BeanUtils.copyProperties(traditionPrice, vo);
            // 公里数
            vo.setMileage(traditionPrice.getMileage());
            // 车型
            vo.setContractVehicle(traditionPrice.getContractVehicle());
            voList.add(vo);
        });
        return voList;
    }

    /**
     * 对象转换 - 针对一口价匹配规则
     *
     * @param fixedPriceList
     * @return
     */
    private List<SdRuleMatchVO> changeFixedPriceToRuleMatch(List<PsupFixedPrice> fixedPriceList) {
        List<SdRuleMatchVO> voList = Lists.newArrayList();
        fixedPriceList.forEach(fixedPrice -> {
            SdRuleMatchVO vo = new SdRuleMatchVO();
            vo.setPriceModel(SdCommonEnum.PRICE_MODEL_FIXED_PRICE.getValue());
            BeanUtils.copyProperties(fixedPrice, vo);
            // 合同车型
            vo.setContractVehicle(fixedPrice.getContractVehicle());
            vo.setMileage(BigDecimal.ONE);
            voList.add(vo);
        });
        return voList;
    }


    /**
     * 对象转换 - 针对其他费用匹配规则
     *
     * @param otherExpensisesList
     * @return
     */
    private List<SdRuleMatchVO> changeOtherExpensisesToRuleMatch(List<PsupOtherExpensises> otherExpensisesList) {
        List<SdRuleMatchVO> voList = Lists.newArrayList();
        otherExpensisesList.forEach(otherExpensises -> {
            SdRuleMatchVO vo = new SdRuleMatchVO();
            BeanUtils.copyProperties(otherExpensises, vo);
            vo.setPriceModel("人送其他费用");
            vo.setPrice(otherExpensises.getGrossAmount());
            // 合同车型
            vo.setContractVehicle(otherExpensises.getContractVehicle());
            vo.setMileage(BigDecimal.ONE);
            voList.add(vo);
        });
        return voList;
    }


    /**
     * 匹配规则数据
     *
     * @param feePayable
     * @param sdRuleMatchVOList
     * @return
     */
    private void matchSdRule(FeePayable feePayable, List<SdRuleMatchVO> sdRuleMatchVOList) {
        if (!CollectionUtils.isEmpty(sdRuleMatchVOList)) {
            KieSession kieSession = KieUtil.getKieContainer().newKieSession();
            sdRuleMatchVOList.forEach(sdRouteMil -> {
                kieSession.insert(sdRouteMil);
            });
            kieSession.insert(feePayable);
            int ruleFiredCount = kieSession.fireAllRules();
            log.info("人送供方线路里程触发了规则共: {}", ruleFiredCount);
            FactHandle factHandle = kieSession.getFactHandle(feePayable);
            if (factHandle != null) {
                kieSession.delete(factHandle);
            }
            kieSession.dispose();
        }
    }

    /**
     * 获取人送基本信息
     *
     * @param feePayable
     * @return
     */
    private List<PsupBaseData> getMatchSdBaseDataInfo(FeePayable feePayable) {
        PsupBaseData conditionBaseData = new PsupBaseData();
        conditionBaseData.setFleetId(feePayable.getFleetId());
        return psupBaseDataService.querySdBaseDataInfoByOrderLevel(conditionBaseData);
    }

    /**
     * 获取对应的标准车型数据
     *
     * @param vehicleClassId
     * @return
     */
    private PsupVehicleContrast getVehicleContrast(String vehicleClassId) {
        if (StringUtils.isNotBlank(vehicleClassId)) {
            EntityWrapper<PsupVehicleContrast> ew = new EntityWrapper<>();
            ew.eq("st_vehicle", vehicleClassId);
            List<PsupVehicleContrast> psupVehicleContrastList = psupVehicleContrastService.selectList(ew);
            if (CollectionUtils.isNotEmpty(psupVehicleContrastList)) {
                return psupVehicleContrastList.get(0);
            }
        }
        return null;
    }

    /**
     * 通用
     *
     * @param feePayable
     * @return
     */
    private EntityWrapper getCommonWrapper(FeePayable feePayable) {
        EntityWrapper ew = new EntityWrapper<>();
        ew.eq("fleet_id", feePayable.getFleetId());
        ew.eq("status", SdCommonEnum.AUDIT.getCode());
        if (Objects.nonNull(feePayable.getOrderDate())) {
            ew.le("effective_date", new DateTime(feePayable.getOrderDate()).toString(ToolCommonUtils.yyyyMMdd));
            ew.ge("invalid_date", new DateTime(feePayable.getOrderDate()).toString(ToolCommonUtils.yyyyMMdd));
        }
        return ew;
    }
}
